<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <title>2022 React 快速入门 | liuz2&#39;s Blog</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1">
    <meta name="generator" content="Hugo 0.63.1" />
    
    
      <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    

    
    
      <link href="/dist/css/app.9576afd3b3c158d98f48ec5df01fec6a.css" rel="stylesheet">
    

    

    
      

    

    

    <meta property="og:title" content="2022 React 快速入门" />
<meta property="og:description" content="本文介绍 React 的基本概念，以 Hooks 写法为主。" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://liuz2.gitee.io/posts/react-quick-start/" />
<meta property="article:published_time" content="2022-02-08T14:22:10+08:00" />
<meta property="article:modified_time" content="2022-02-08T14:22:10+08:00" />
<meta itemprop="name" content="2022 React 快速入门">
<meta itemprop="description" content="本文介绍 React 的基本概念，以 Hooks 写法为主。">
<meta itemprop="datePublished" content="2022-02-08T14:22:10&#43;08:00" />
<meta itemprop="dateModified" content="2022-02-08T14:22:10&#43;08:00" />
<meta itemprop="wordCount" content="555">



<meta itemprop="keywords" content="react," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="2022 React 快速入门"/>
<meta name="twitter:description" content="本文介绍 React 的基本概念，以 Hooks 写法为主。"/>

	
  </head>

  <body class="ma0 avenir bg-white">

    
   
  

  <header>
    <div class="bg-black">
      <nav class="pv3 ph3 ph4-ns" role="navigation">
  <div class="flex-l justify-between items-center center">
    <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
      
        liuz2&#39;s Blog
      
    </a>
    <div class="flex-l items-center">
      

      
        <ul class="pl0 mr3">
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/about/" title="About page">
              About
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/links/" title="Links page">
              Links
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/timeline/" title="Timeline page">
              Timeline
            </a>
          </li>
          
        </ul>
      
      















    </div>
  </div>
</nav>

    </div>
  </header>



    <main class="pb7" role="main">
      
  
  <article class="flex-l flex-wrap justify-between mw8 center ph3">
    <header class="mt4 w-100">
      <h1 class="f3 athelas mt3 mb1">2022 React 快速入门</h1>
      
      
      <time class="f6 mv1 dib tracked" datetime="2022-02-08T14:22:10&#43;08:00">February 8, 2022</time>

      
      
    </header>
    <div class="nested-copy-line-height lh-copy sans-serif f5 nested-links nested-img mid-gray pr4-l w-two-thirds-l"><blockquote>
<p>本文翻译自 <a href="https://beta.reactjs.org/learn">Quick Start - React Beta 官方文档</a>。新版文档以 Hooks 写法为主。</p>
</blockquote>
<h2 id="组件的创建和嵌套">组件的创建和嵌套</h2>
<p>React 应用由组件构成。组件就是一段代码，包含自己状态和逻辑。在 React 中，组件就是一个普通 JavaScript 函数，返回值是一些标签元素：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyButton</span>() {
    <span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">button</span>&gt;<span style="color:#a6e22e">Click</span> <span style="color:#a6e22e">me</span>&lt;/<span style="color:#f92672">button</span>&gt;;
}
</code></pre></div><p>创建组件 <code>MyButton</code> 后，可以在其他组件嵌套使用：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyApp</span>() {
    <span style="color:#66d9ef">return</span> (
        &lt;<span style="color:#f92672">div</span>&gt;
            &lt;<span style="color:#f92672">h1</span>&gt;<span style="color:#a6e22e">Welcome</span> <span style="color:#a6e22e">to</span> <span style="color:#a6e22e">my</span> <span style="color:#a6e22e">app</span>&lt;/<span style="color:#f92672">h1</span>&gt;
            &lt;<span style="color:#f92672">MyButton</span> /&gt;
        &lt;/<span style="color:#f92672">div</span>&gt;
    );
}
</code></pre></div><p>注意，<code>&lt;MyButton /&gt;</code> 以大写字母开头，这是 React 组件的独特标识。React 组件标签首字母必须是大写字母，而 HTML 原生标签必须是小写字母。</p>
<h2 id="使用-jsx-编写标记">使用 JSX 编写标记</h2>
<p>上面的标记语法叫做 JSX。使用 JSX 可以简化代码编写。所有的 <a href="https://beta.reactjs.org/learn/installation">React 脚手架工具</a>开箱支持 JSX。</p>
<p>JSX 比 HTML 稍严。需要自关闭标签，比如 <code>&lt;br /&gt;</code>。组件不能返回多个 JSX 标签。需要使用一个共同的父组件把它们包裹返回，比如 <code>&lt;div&gt;...&lt;/div&gt;</code> 或空的 <code>&lt;&gt;...&lt;/&gt;</code> 等：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">AboutPage</span>() {
    <span style="color:#66d9ef">return</span> (
        <span style="color:#f92672">&lt;</span><span style="color:#f92672">&gt;</span>
            &lt;<span style="color:#f92672">h1</span>&gt;<span style="color:#a6e22e">About</span>&lt;/<span style="color:#f92672">h1</span>&gt;
            &lt;<span style="color:#f92672">p</span>&gt;
                <span style="color:#a6e22e">Hello</span> <span style="color:#a6e22e">there</span>. &lt;<span style="color:#f92672">br</span> /&gt; <span style="color:#a6e22e">How</span> <span style="color:#66d9ef">do</span> <span style="color:#a6e22e">you</span> <span style="color:#66d9ef">do</span><span style="color:#f92672">?</span>
            &lt;/<span style="color:#f92672">p</span>&gt;
        <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/</span><span style="color:#960050;background-color:#1e0010">&gt;</span>
    );
}
</code></pre></div><p>如果你有很多 HTML 标签要转换成 JSX，可以使用<a href="https://transform.tools/html-to-jsx">在线工具</a>。</p>
<h2 id="增加样式">增加样式</h2>
<p>在 React 中，使用 <code>className</code> 增加 CSS 类。它和 HTML 的 <code>class</code> 属性作用一样：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx">&lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">className</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;avatar&#34;</span> /&gt;
</code></pre></div><p>然后，就可以在独立的 CSS 文件中为它编写规则：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-css" data-lang="css"><span style="color:#75715e">/* 在 CSS 文件中 */</span>
.<span style="color:#a6e22e">avatar</span> {
    <span style="color:#66d9ef">border-radius</span>: <span style="color:#ae81ff">50</span><span style="color:#66d9ef">%</span>;
}
</code></pre></div><p>React 没有规定如何引入 CSS 文件。最简单的做法，就是在 HTML 中增加 <code>&lt;link&gt;</code> 标签。如果你使用构建工具或框架，可以参照各自的说明文档，决定具体到的 CSS 文件引入方式。</p>
<h2 id="展示数据">展示数据</h2>
<p>JSX 让你在 JavaScript 中使用标签。而花括号让你“重返” JavaScript 模式，此时你可以在代码中嵌套展示一些 JS 变量。比如，下面代码展示了 <code>user.name</code> 变量：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">h1</span>&gt;{<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">name</span>}&lt;/<span style="color:#f92672">h1</span>&gt;;
</code></pre></div><p>也可以在 JSX 属性中使用 JavaScript 变量，但要记得使用花括号代替引号。比如，<code>className=&quot;avatar&quot;</code> 将 <code>&quot;avatar&quot;</code> 字符串当作 CSS 类，而 <code>src={user.imageUrl}</code> 会读取 <code>user.imageUrl</code> 变量，然后将它作为 <code>src</code> 属性的值：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">className</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;avatar&#34;</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">imageUrl</span>} /&gt;;
</code></pre></div><p>还可以在 JSX 花括号中使用复杂表达式，比如字符串拼接：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">Profile</span>() {
    <span style="color:#66d9ef">return</span> (
        <span style="color:#f92672">&lt;</span><span style="color:#f92672">&gt;</span>
            &lt;<span style="color:#f92672">h1</span>&gt;{<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">name</span>}&lt;/<span style="color:#f92672">h1</span>&gt;
            &lt;<span style="color:#f92672">img</span>
                <span style="color:#a6e22e">className</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;avatar&#34;</span>
                <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">imageUrl</span>}
                <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span>{<span style="color:#e6db74">&#39;Photo of &#39;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">name</span>}
                <span style="color:#a6e22e">style</span><span style="color:#f92672">=</span>{{
                    <span style="color:#a6e22e">width</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">imageSize</span>,
                    <span style="color:#a6e22e">height</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">imageSize</span>,
                }}
            /&gt;
        <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/</span><span style="color:#960050;background-color:#1e0010">&gt;</span>
    );
}
</code></pre></div><p>在上面的例子中，<code>style={{}}</code> 不是特殊语法，而是普通的 <code>{}</code> 对象和 <code>style={}</code> JSX 花括号叠加使用的结果。</p>
<h2 id="条件渲染">条件渲染</h2>
<p>在 React 中，条件语句没有特殊语法。你只需要使用普通的 JS 代码即可。比如，可以使用 <code>if</code> 语句：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">let</span> <span style="color:#a6e22e">content</span>;
<span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">isLoggedIn</span>) {
    <span style="color:#a6e22e">content</span> <span style="color:#f92672">=</span> &lt;<span style="color:#f92672">AdminPanel</span> /&gt;;
} <span style="color:#66d9ef">else</span> {
    <span style="color:#a6e22e">content</span> <span style="color:#f92672">=</span> &lt;<span style="color:#f92672">LoginForm</span> /&gt;;
}

<span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">div</span>&gt;{<span style="color:#a6e22e">content</span>}&lt;/<span style="color:#f92672">div</span>&gt;;
</code></pre></div><p>如果偏爱紧凑代码，可以使用 <code>?:</code> 三目运算符。JSX 中不能使用 <code>if</code> 语句，但是可以使用三目运算符：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx">&lt;<span style="color:#f92672">div</span>&gt;{<span style="color:#a6e22e">isLoggedIn</span> <span style="color:#f92672">?</span> &lt;<span style="color:#f92672">AdminPanel</span> /&gt; <span style="color:#f92672">:</span> &lt;<span style="color:#f92672">LoginForm</span> /&gt;}&lt;/<span style="color:#f92672">div</span>&gt;
</code></pre></div><p>如果不需要 <code>else</code> 分支，还可以使用更短的逻辑与 <code>&amp;&amp;</code> 语法：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx">&lt;<span style="color:#f92672">div</span>&gt;{<span style="color:#a6e22e">isLoggedIn</span> <span style="color:#f92672">&amp;&amp;</span> &lt;<span style="color:#f92672">AdminPanel</span> /&gt;}&lt;/<span style="color:#f92672">div</span>&gt;
</code></pre></div><h2 id="渲染列表">渲染列表</h2>
<p>可以使用 JS 的 <code>for</code> 循环和数组的 <code>map()</code> 函数渲染组件列表。</p>
<p>比如，我们有如下产品列表：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">products</span> <span style="color:#f92672">=</span> [
    { <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;Cabbage&#39;</span>, <span style="color:#a6e22e">id</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">1</span> },
    { <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;Garlic&#39;</span>, <span style="color:#a6e22e">id</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">2</span> },
    { <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;Apple&#39;</span>, <span style="color:#a6e22e">id</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">3</span> },
];
</code></pre></div><p>在组件中，就可以使用 <code>map()</code> 函数，将产品数组转化为 <code>&lt;li&gt;</code> 元素数组：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">listItems</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">products</span>.<span style="color:#a6e22e">map</span>((<span style="color:#a6e22e">product</span>) =&gt; (
    &lt;<span style="color:#f92672">li</span> <span style="color:#a6e22e">key</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">product</span>.<span style="color:#a6e22e">id</span>}&gt;{<span style="color:#a6e22e">product</span>.<span style="color:#a6e22e">title</span>}&lt;/<span style="color:#f92672">li</span>&gt;
));

<span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">ul</span>&gt;{<span style="color:#a6e22e">listItems</span>}&lt;/<span style="color:#f92672">ul</span>&gt;;
</code></pre></div><p>注意，<code>&lt;li&gt;</code> 有一个 <code>key</code> 属性。列表中的每一个元素，都应该有一个独特的标识符。通常，key 来自你的数据，比如数据库 ID。React 根据 key 值辨别元素的不同操作，比如增加、删除、重新排序等。</p>
<h2 id="处理事件">处理事件</h2>
<p>可以在组件内声明事件处理函数：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyButton</span>() {
    <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">handleClick</span>() {
        <span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#39;You clicked me!&#39;</span>);
    }

    <span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">button</span> <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">handleClick</span>}&gt;<span style="color:#a6e22e">Click</span> <span style="color:#a6e22e">me</span>&lt;/<span style="color:#f92672">button</span>&gt;;
}
</code></pre></div><p>注意，<code>onClick={handleClick}</code> 结尾处没有圆括号！不要执行事件处理函数：只需将其传递进来即可。当用户点击按钮，React 会执行这个事件处理函数。</p>
<h2 id="更新屏幕">更新屏幕</h2>
<p>我们经常希望组件可以“记住”某些信息，并展示出来。比如，我们想统计一个按钮的点击次数。此时，我们可以为组件增加“状态”。</p>
<p>首先，从 React 引入 <code>useState</code>：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">useState</span> } <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;react&#39;</span>;
</code></pre></div><p>此时，我们可以在组件中声明一个状态变量：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyButton</span>() {
    <span style="color:#66d9ef">const</span> [<span style="color:#a6e22e">count</span>, <span style="color:#a6e22e">setCount</span>] <span style="color:#f92672">=</span> <span style="color:#a6e22e">useState</span>(<span style="color:#ae81ff">0</span>);
}
</code></pre></div><p>从 <code>useState</code> 中可以得到两个东西：当前状态（<code>state</code>），和更新状态的函数（<code>setCount</code>）。我们可以使用任意名称，但是惯例写法是 <code>[something, setSomething]</code>。</p>
<p>按钮第一次渲染时，<code>count</code> 是 <code>0</code>，因为我们传递给 <code>useState()</code> 的初始值是 <code>0</code>。当需要改变状态时，调用 <code>setCount()</code> 并将新值传给它即可。点击按钮就可以增加计数：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyButton</span>() {
    <span style="color:#66d9ef">const</span> [<span style="color:#a6e22e">count</span>, <span style="color:#a6e22e">setCount</span>] <span style="color:#f92672">=</span> <span style="color:#a6e22e">useState</span>(<span style="color:#ae81ff">0</span>);

    <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">handleClick</span>() {
        <span style="color:#a6e22e">setCount</span>(<span style="color:#a6e22e">count</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>);
    }

    <span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">button</span> <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">handleClick</span>}&gt;<span style="color:#a6e22e">Clicked</span> {<span style="color:#a6e22e">count</span>} <span style="color:#a6e22e">times</span>&lt;/<span style="color:#f92672">button</span>&gt;;
}
</code></pre></div><p>随着按钮的点击，<code>count</code> 会变为 <code>1</code>，然后变为 <code>2</code>，等等。</p>
<p>如果多次渲染同一组件，每个都会有自己的状态。尝试分别点击不同的按钮：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyApp</span>() {
    <span style="color:#66d9ef">return</span> (
        &lt;<span style="color:#f92672">div</span>&gt;
            &lt;<span style="color:#f92672">h1</span>&gt;<span style="color:#a6e22e">Counters</span> <span style="color:#a6e22e">that</span> <span style="color:#a6e22e">update</span> <span style="color:#a6e22e">separately</span>&lt;/<span style="color:#f92672">h1</span>&gt;
            &lt;<span style="color:#f92672">MyButton</span> /&gt;
            &lt;<span style="color:#f92672">MyButton</span> /&gt;
            &lt;<span style="color:#f92672">MyButton</span> /&gt;
        &lt;/<span style="color:#f92672">div</span>&gt;
    );
}
</code></pre></div><h2 id="使用-hooks">使用 Hooks</h2>
<p>以 <code>use</code> 开头的函数称作 <strong>Hooks</strong>。<code>useState</code> 是 React 提供的内置 Hook。可以从 <a href="https://beta.reactjs.org/apis">React API reference</a> 查看其余内置 Hooks。我们还可以利用现有 Hooks，生成新 Hooks。</p>
<p>Hooks 比普通函数有更多的限制。只可以在组件（或其他 Hooks）的根作用域调用 Hooks。如果需要在条件语句或循环中使用 <code>useState</code>，可以提取新组件，然后在新组件中使用它。</p>
<h2 id="组件间共享数据">组件间共享数据</h2>
<p>在上述例子中，每个组件都有各自独立的计数：</p>
<pre><code>- MyApp
    - MyButton (count: 3)
    - MyButton (count: 1)
    - MyButton (count: 2)
</code></pre><p>然而，有时候我们需要不同组件共享数据，同时更新状态。</p>
<p>如果想让所有按钮显示同样的 <code>count</code>，保持状态同步，需要将状态从独立的按钮提取出来，放入最近的父容器。在这个例子中，是 <code>MyApp</code>:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#f92672">-</span> <span style="color:#a6e22e">MyApp</span> (<span style="color:#a6e22e">count</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">3</span>)
    <span style="color:#f92672">-</span> <span style="color:#a6e22e">MyButton</span>
    <span style="color:#f92672">-</span> <span style="color:#a6e22e">MyButton</span>
    <span style="color:#f92672">-</span> <span style="color:#a6e22e">MyButton</span>
</code></pre></div><p>以下是具体的代码实现：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-jsx" data-lang="jsx"><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyButton</span>({ <span style="color:#a6e22e">count</span>, <span style="color:#a6e22e">onClick</span> }) {
    <span style="color:#75715e">// 3. 使用传入的属性
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">return</span> &lt;<span style="color:#f92672">button</span> <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">onClick</span>}&gt;<span style="color:#a6e22e">Clicked</span> {<span style="color:#a6e22e">count</span>} <span style="color:#a6e22e">times</span>&lt;/<span style="color:#f92672">button</span>&gt;;
}

<span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">MyApp</span>() {
    <span style="color:#75715e">// 1. 首先，把子组件的状态变量提升到父容器
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> [<span style="color:#a6e22e">count</span>, <span style="color:#a6e22e">setCount</span>] <span style="color:#f92672">=</span> <span style="color:#a6e22e">useState</span>(<span style="color:#ae81ff">0</span>);

    <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">handleClick</span>() {
        <span style="color:#a6e22e">setCount</span>(<span style="color:#a6e22e">count</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>);
    }

    <span style="color:#66d9ef">return</span> (
        &lt;<span style="color:#f92672">div</span>&gt;
            &lt;<span style="color:#f92672">h1</span>&gt;<span style="color:#a6e22e">Counters</span> <span style="color:#a6e22e">that</span> <span style="color:#a6e22e">update</span> <span style="color:#a6e22e">separately</span>&lt;/<span style="color:#f92672">h1</span>&gt;
            {<span style="color:#75715e">/* 2. 将状态和事件处理函数传入每个子组件 */</span>}
            &lt;<span style="color:#f92672">MyButton</span> <span style="color:#a6e22e">count</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">count</span>} <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">handleClick</span>} /&gt;
            &lt;<span style="color:#f92672">MyButton</span> <span style="color:#a6e22e">count</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">count</span>} <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">handleClick</span>} /&gt;
            &lt;<span style="color:#f92672">MyButton</span> <span style="color:#a6e22e">count</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">count</span>} <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">handleClick</span>} /&gt;
        &lt;/<span style="color:#f92672">div</span>&gt;
    );
}
</code></pre></div><p>当你点击按钮时，会触发 <code>onClick</code> 处理函数。每个按钮的 <code>onClick</code> 属性都指向 <code>MyApp</code> 中的 <code>handleClick</code> 函数，此时会触发其中的 <code>setCount(count + 1)</code>，增加 <code>count</code> 状态变量。新的 <code>count</code> 变量会当作属性传给每个按钮，因此它们最终都会显示相同的值。</p>
<p>这叫做“提升状态变量”。通过提升，我们可以在不同组件间共享状态变量。</p>
<h2 id="下一步">下一步</h2>
<p>现在，我们已经掌握了 React 的基本用法！</p>
<p>访问 <a href="https://beta.reactjs.org/learn/thinking-in-react">Thinking in React</a>，可以看看实际的 React 开发时怎样的。</p>
<a href="https://gitee.com/liuz2/liuz2/blob/master/content/posts/react-quick-start.md#tree_comm_title" class="no-underline db b--black pa2 tc bg-black-90" style="color:#eee;">进入留言</a><ul class="pa0">
  
   <li class="list dib">
     <a href="/tags/react" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">react</a>
   </li>
  
</ul>
<div class="mt6 instapaper_ignoref">
      
      
      </div>
    </div>

    <aside class="w-30-l mt6-l"><div class="bg-light-gray pa3 nested-list-reset nested-copy-line-height nested-links">
    <p class="f5 b mb3">目录</p>
      <nav id="TableOfContents">
  <ul>
    <li><a href="#组件的创建和嵌套">组件的创建和嵌套</a></li>
    <li><a href="#使用-jsx-编写标记">使用 JSX 编写标记</a></li>
    <li><a href="#增加样式">增加样式</a></li>
    <li><a href="#展示数据">展示数据</a></li>
    <li><a href="#条件渲染">条件渲染</a></li>
    <li><a href="#渲染列表">渲染列表</a></li>
    <li><a href="#处理事件">处理事件</a></li>
    <li><a href="#更新屏幕">更新屏幕</a></li>
    <li><a href="#使用-hooks">使用 Hooks</a></li>
    <li><a href="#组件间共享数据">组件间共享数据</a></li>
    <li><a href="#下一步">下一步</a></li>
  </ul>
</nav>
  </div>




</aside>

  </article>

    </main>
    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
  <div class="flex justify-between">
  <a class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3" href="https://liuz2.gitee.io/" >
    &copy;  liuz2's Blog 2022 
  </a>
    <div>














</div>
  </div>
</footer>

    

  <script src="/dist/js/app.3fc0f988d21662902933.js"></script>


  </body>
</html>
